package com.loveyukari.service;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

import com.loveyukari.dao.LiwuHistoryDao;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import com.loveyukari.common.exception.InternalException;
import com.loveyukari.dao.LiwuDao;
import com.loveyukari.dao.LiwuStyleDao;
import com.loveyukari.model.Auth;
import com.loveyukari.model.Liwu;
import com.loveyukari.model.LiwuStyle;
import com.loveyukari.utils.HttpUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
*
*yangshaohua
*2016年12月16日下午6:13:44
**/

@Service
public class LiwuService {

	private Logger log = LoggerFactory.getLogger(LiwuStyle.class);
	
	@Autowired
	private LiwuDao liwuDao;
	@Autowired
	private LiwuHistoryDao liwuHistoryDao;
	
	@Autowired
	private LiwuStyleDao liwuStyleDao;
	
	@Autowired
	private AuthService authService;

	@Autowired
	private RedisService redisService;
	

	private static final String LIWU_STYLE_KEY = "liwu:style:v2:";

	public void addHistroy(InputStream fileInput,Date date) throws Exception {
		BufferedReader reader = new BufferedReader(new InputStreamReader(fileInput, "utf-8"));
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        HashMap<Integer, Map<Integer,List<Liwu>>> map = new HashMap<>();
		while(true){
			String line = reader.readLine();
			if (line == null){
				break;
			}
			String[] ss = line.split(" - ");
			String dateStr = ss[0].substring(1,20);
			String l = ss[1];
			JSONObject json = null;
			try {
				json = JSONObject.fromObject(l);
			} catch (Exception e) {
				continue;
			}
			if (json == null || json.isEmpty()){
				log.info("line error: "+l);
			}
			String type = json.optString("type");
			int uid = -1;
			int gfid = -1;
			int hits = 1;

			if ("dgb".equals(type)){
				uid = json.optInt("uid",-1);
				gfid = json.optInt("gfid",-1);
				hits = json.optInt("hits",1);
			} else if ("bc_buy_deserve".equals(type)){
				uid = json.optInt("sid",-1);
				gfid = json.optInt("lev",-1);
				hits = json.optInt("hits",1);
			} else if ("anbc".equals(type)){
                uid = json.optInt("sid",-1);
                gfid = json.optInt("nl",-1);
                if (gfid != -1){
                    gfid += 10;
                }
            }

            if (uid == -1 || gfid == -1){
			    continue;
            }
            Date giveTime = sdf.parse(dateStr);

			Map<Integer, List<Liwu>> liwuMap =  map.get(uid);
			if (liwuMap == null){
				liwuMap = new HashMap<>();
				map.put(uid,liwuMap);
			}
			List<Liwu> liwuList = liwuMap.get(gfid);
			if(liwuList == null){
				liwuList = new ArrayList<>();
				liwuMap.put(gfid,liwuList);
			}
			Liwu liwu = new Liwu();
			liwu.setUid(uid);
			liwu.setGfid(gfid);
			liwu.setHits(hits);
			liwu.setGiveTime(giveTime);
			liwuList.add(liwu);

			//用于之后
//			if(liwuList.isEmpty()){
//				Liwu liwu = new Liwu();
//				liwu.setUid(uid);
//				liwu.setGfid(gfid);
//				liwu.setHits(hits);
//				liwu.setGiveTime(giveTime);
//				liwuList.add(liwu);
//			} else {
//				Liwu liwu = liwuList.get(liwuList.size() - 1);
//				if (hits - liwu.getHits() == 1){
//					liwu.setHits(hits);
//					liwu.setGiveTime(giveTime);
//				} else {
//					liwu = new Liwu();
//					liwu.setUid(uid);
//					liwu.setGfid(gfid);
//					liwu.setHits(hits);
//					liwu.setGiveTime(giveTime);
//					liwuList.add(liwu);
//				}
//			}

		}

		ArrayList<Liwu> insertLiwuList = new ArrayList<Liwu>();
		Set<Integer> uidSet = map.keySet();
		Map<Integer, Map<Integer, Liwu>> dbMap = liwuHistoryDao.selectLiwuByDate(date);
		int time = 3600000;

		for (Integer uid:uidSet
			 ) {
			Map<Integer, List<Liwu>> liwuMap = map.get(uid);
			Map<Integer, Liwu> dbLiwuMap = dbMap.get(uid);
			if (dbLiwuMap == null){
				dbLiwuMap = new HashMap<>();
			}
			Set<Integer> gfidSet = liwuMap.keySet();
			for (Integer gfid :
					gfidSet) {
				Liwu dbLiwu = dbLiwuMap.get(gfid);
//				Liwu dbLiwu = liwuHistoryDao.selectLiwuByUidAndGfid(uid,gfid);
				boolean updateFlag = false;
				List<Liwu> liwus = liwuMap.get(gfid);
				for (int i = 0; i < liwus.size(); i++) {
					Liwu liwu = liwus.get(i);
					Liwu lastLiwu = null;
					if (i == 0){
						if (dbLiwu != null && liwu.getHits() > dbLiwu.getHits() && liwu.getGiveTime().getTime() - dbLiwu.getGiveTime().getTime() <= time){
							lastLiwu = dbLiwu;
							updateFlag = true;
						}
					} else {
						lastLiwu = liwus.get(i-1);
					}
					if (lastLiwu != null ){
						long lastTime = lastLiwu.getGiveTime().getTime();
						long nowTime = liwu.getGiveTime().getTime();
						boolean t2 = nowTime - lastTime > time;
						if (liwu.getHits() <= lastLiwu.getHits()){
							if (liwu.getHits() == 1 && !t2){
								liwu.setHits(lastLiwu.getHits()+1);
							} else {
								if (updateFlag){
									lastLiwu.setId(dbLiwu.getId());
									liwuHistoryDao.updateLiwu(lastLiwu);
								} else {
									insertLiwuList.add(lastLiwu);
								}
							}
						} else if (t2) {
							if (updateFlag){
								lastLiwu.setId(dbLiwu.getId());
								liwuHistoryDao.updateLiwu(lastLiwu);
							} else {
								insertLiwuList.add(lastLiwu);
							}
						}
					}
					if (i == liwus.size() - 1) {
						if (updateFlag) {
							liwu.setId(dbLiwu.getId());
							liwuHistoryDao.updateLiwu(liwu);
						} else {
							insertLiwuList.add(liwu);
						}
					}
				}
			}
		}
		liwuHistoryDao.batchInsertLiwu(insertLiwuList);
		reader.close();
	}







	
	public List<Liwu> getLiwu(int size){
		List<Liwu> list = liwuDao.selectLiwuByRead(size);
		Iterator<Liwu> iterator = list.iterator();
		while(iterator.hasNext()){
			Liwu liwu = iterator.next();
			LiwuStyle liwuStyle = this.getLiwuStyle(liwu.getGfid());
			if (liwuStyle == null){
				iterator.remove();
			} else {
				liwu.setLiwuStyle(liwuStyle);
			}
			Auth auth = authService.getCacheAuth(liwu.getUid());
			if (auth == null){
				iterator.remove();
			} else {
				liwu.setAuth(auth);
			}
		}
		return list;
	}
	
	public void markRead(int id){
		Liwu liwu = liwuDao.selectLiwuById(id);
		liwu.setStatus(-1);
		liwuDao.updateLiwu(liwu);
	}
	
	public void closeLiwu(List<Integer> ids){
		liwuDao.updateLiwuStatus(-1, ids);
	}
	
	private LiwuStyle getLiwuStyle(int gfid){
		String key = LIWU_STYLE_KEY+gfid;
		LiwuStyle liwuStyle = redisService.get(key,LiwuStyle.class);
		if (liwuStyle == null){
			List<LiwuStyle> list = liwuStyleDao.selectLiwuStyleList();
			for (LiwuStyle style : list) {
				redisService.set(LIWU_STYLE_KEY+style.getGfid(), style);
			}
		}
		liwuStyle = redisService.get(key,LiwuStyle.class);
		return liwuStyle;
	}
	
	
	public void reloadStyleMap(){
		Set<String> keys = redisService.keys(LIWU_STYLE_KEY + "*");
		redisService.del(keys);
	}
	
	public LiwuStyle getLiwuStyleByGfid(Integer gfid){
		if (gfid == null || gfid == 0) return null;
		LiwuStyle liwuStyle = this.getLiwuStyle(gfid);
		if (liwuStyle == null){
			this.addLiwuStyle();
			liwuStyle = getLiwuStyle(gfid);
		}
		return liwuStyle;
	}


	public void addLiwuStyle(){
		log.info("add liwu style start");
		try {
			//房间礼物信息
			String room = HttpUtils.sendGet("https://www.douyu.com/ztCache/WebM/room/196");
			JSONObject roomJson = JSONObject.fromObject(JSONObject.fromObject(room).opt("$ROOM"));
//			String room = HttpUtils.sendGet("https://www.douyu.com/196");
//			String str = "var $ROOM = ";
//			int indexGift = room.indexOf(str);
//			JSONObject roomJson = JSONObject.fromObject(room.substring(indexGift+str.length(), room.indexOf(";", indexGift)));
			int giftTempId = roomJson.optInt("giftTempId");
			String context = HttpUtils.sendGet("https://webconf.douyucdn.cn//resource/common/gift/gift_template/"+giftTempId+".json");
			context = StringUtils.substring(context, StringUtils.indexOf(context, "{"),StringUtils.lastIndexOf(context, "}")+1);
			JSONArray roomLiwuStyleList = JSONObject.fromObject(context).getJSONArray("data");
			for (int i = 0; i < roomLiwuStyleList.size(); i++) {
				try {
					JSONObject roomLiwuStyle = roomLiwuStyleList.getJSONObject(i);
					int gfid = roomLiwuStyle.getInt("id");
					addLiwuStyle(gfid, roomLiwuStyle);
				} catch (Exception e) {
					log.error(e.getMessage(),e);
				}
			}
		} catch (Exception e) {
			log.error(e.getMessage(),e);
		}
		try {
			//定制礼物信息
			String context = HttpUtils.sendGet("https://webconf.douyucdn.cn//resource/common/prop_gift_list/prop_gift_config.json");
			context = StringUtils.substring(context, StringUtils.indexOf(context, "{"),StringUtils.lastIndexOf(context, "}")+1);
			JSONObject customLiwuStyleMap = JSONObject.fromObject(context).getJSONObject("data");
			JSONArray customLiwuStyleNames = customLiwuStyleMap.names();
			for (int i = 0; i < customLiwuStyleNames.size(); i++) {
				try {
					String gfidStr = customLiwuStyleNames.getString(i);
					JSONObject customLiwuStyle = customLiwuStyleMap.getJSONObject(gfidStr);
					int gfid = Integer.parseInt(gfidStr);
					addLiwuStyle(gfid, customLiwuStyle);
				} catch (Exception e) {
					log.error(e.getMessage(),e);
				}
			}
		} catch (Exception e) {
			log.error(e.getMessage(),e);
		}
		this.reloadStyleMap();
		log.info("add liwu style end");
	}
	
	private void addLiwuStyle(int gfid,JSONObject liwuStyleJson){
		String bimg = liwuStyleJson.optString("bimg");
		String himg = liwuStyleJson.optString("himg");
		String urgb = liwuStyleJson.optString("urgb");
		String drgb = liwuStyleJson.optString("drgb");
		String name = liwuStyleJson.optString("name");
		String grgb = liwuStyleJson.optString("grgb");
		String brgb = liwuStyleJson.optString("brgb");
		String cimg = liwuStyleJson.optString("cimg");
		String pcFullIcon = liwuStyleJson.optString("pc_full_icon");
		String pcFullBgIcon = liwuStyleJson.optString("pc_full_bg_icon");
		int hitInterval = liwuStyleJson.optInt("hit_interval");
		int style = liwuStyleJson.getInt("style");
		int pc = liwuStyleJson.getInt("pc");
		LiwuStyle liwuStyle = new LiwuStyle();
		liwuStyle.setGfid(gfid);
		liwuStyle.setBimg(bimg);
		liwuStyle.setHimg(himg);
		liwuStyle.setUrgb(urgb);
		liwuStyle.setBrgb(brgb);
		liwuStyle.setName(name);
		liwuStyle.setDrgb(drgb);
		liwuStyle.setGrgb(grgb);
		liwuStyle.setStyle(style);
		liwuStyle.setPc(pc);
		liwuStyle.setHitInterval(hitInterval);
		liwuStyle.setPcFullIcon(pcFullIcon);
		liwuStyle.setPcFullBgIcon(pcFullBgIcon);
		liwuStyle.setCimg(cimg);
		if (liwuStyleDao.selectLiwuStyleByGfid(gfid) == null){
			liwuStyleDao.insertLiwuStyle(liwuStyle);
		} else {
			liwuStyleDao.updateLiwuStyle(liwuStyle);
		}
	}
	
	
	public void addLiwu(int gfid,int authId,int hits){
		Liwu liwu = new Liwu();
		liwu.setGfid(gfid);
		liwu.setGiveTime(new Date());
		liwu.setHits(hits);
		liwu.setUid(authId);
		liwuDao.insertLiwu(liwu);
	}
	
	public void updateLiwu(Liwu liwu){
		liwuDao.updateLiwu(liwu);
	}
	
	public Liwu getLiwuByAuthAndGfid(int authId,int gfid){
		return this.liwuDao.selectLiwuByUidAndGfid(authId, gfid);
	}

	public void autoCloasLiwu(){
		List<Liwu> list = this.getLiwu(-1);
		List<Integer> ids = new ArrayList<Integer>();
		long time = System.currentTimeMillis() - 3600000*24;
		for (Liwu liwu : list) {
			if (liwu.getGiveTime().getTime() < time){
				ids.add(liwu.getId());
			}
		}
		this.closeLiwu(ids);
	}

	private static final String HIDE_LIWU_STYLE_IDS = "liwu:style:hide:ids";
	public List<Integer> getHideLiwuStyleIds(){
		List<Integer> list = redisService.rangList(HIDE_LIWU_STYLE_IDS, Integer.class);
		if (list == null){
			return new ArrayList<>();
		}
		return list;
	}

	public void setHideLiwuStyleIds(Integer[] ids){
		ArrayList<Integer> list = new ArrayList<>();
		for(int i=0;i<ids.length;i++){
			if (this.getLiwuStyle(ids[i]) != null){
				list.add(ids[i]);
			}
		}
		redisService.del(HIDE_LIWU_STYLE_IDS);
		if (!list.isEmpty()){
			redisService.setListAll(HIDE_LIWU_STYLE_IDS,list);
		}
	}

}
